package myadmin.jtthink.com.MyHelper;



import myadmin.jtthink.com.MyAnnotations.GET;
import myadmin.jtthink.com.MyAnnotations.MethodName;
import myadmin.jtthink.com.MyAnnotations.POST;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.ApplicationContext;
import org.springframework.core.annotation.AnnotationUtils;
import org.springframework.stereotype.Component;
import org.springframework.web.context.request.ServletWebRequest;

import javax.servlet.http.HttpServletRequest;
import java.lang.annotation.Annotation;
import java.lang.reflect.Method;
import java.lang.reflect.Parameter;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;


@Component
public class ServiceHelper {
    @Autowired
    ApplicationContext applicationContext;
    @Autowired
     ServiceParam serviceParam;
    List<Class> requestMethods= Arrays.asList(GET.class, POST.class);

    public Object invoke(Object[] args) throws Exception {
        if(args.length!=3) throw new Exception("error params");
        return this.invoke(args[0].toString(),args[1].toString(),(HttpServletRequest)args[2]);
    }
    public Object invoke(String sname, String mname, HttpServletRequest request) throws Exception {
        Object bean=applicationContext.getBean(sname+"Service");
        Class objClass=bean.getClass();
        Method getMethod= this.getMethod(objClass,mname);
        //检查请求方式是否匹配
        if(!this.checkRequestMethod(getMethod,request.getMethod())){
            throw new Exception("method not allowed");
        }
        List<Object> params=this.checkParams(getMethod,request);
        return getMethod.invoke(bean,params.toArray());
    }
    //映射query 参数和service 方法参数
    private List<Object> checkParams(Method method,HttpServletRequest request) throws Exception {
        List<Object> ret=new ArrayList<>();
        Parameter[] parameters=method.getParameters();

        ServletWebRequest servletWebRequest=new ServletWebRequest(request);
        int index=0;
        for(Parameter p:parameters){
                Object pObj=this.serviceParam.parseParam(method,index,servletWebRequest);
                ret.add(pObj);
                index++;
//            if(request.getParameterMap().containsKey(p.getName())){//query参数
//                ret.add(ServiceUtil.convertQuery(p,request.getParameterMap().get(p.getName())[0]));
//            }else{
//                throw new Exception("params err");
//            }
        }
        return ret;
    }
     //获取反射方法，需要解析自定义注解
    private Method getMethod(Class<?> objClass,String mname) throws NoSuchMethodException {

        for(Method method:objClass.getMethods()){
          Annotation getAnno= AnnotationUtils.findAnnotation(method,MethodName.class);
          if(getAnno!=null && ((MethodName) getAnno).value().equals(mname)){
              return method;
          }
        }
        throw new NoSuchMethodException(mname);
    }

    //检查请求方式是否匹配，没有打注解，则一律是GET
    private boolean checkRequestMethod(Method method,String requestMethod){
        boolean isSetMethod=false;
        for ( Class m : this.requestMethods){
            //这里做了改动，由于是AOP来执行。因此要使用findAnnotation
            Annotation getAnno= AnnotationUtils.findAnnotation(method,m);
            if(getAnno!=null){
                isSetMethod=true;
                if(AnnotationUtils.getAnnotationAttributes(getAnno).get("value").equals(requestMethod)){
                    return true;
                }
            }
        }
        //代表打了 注解，但是一个都没匹配到
        if(isSetMethod) return false;
        if(requestMethod.equals("GET")) return true ; //如果没打注解，默认就是GET
        return  false;
    }



}
